package com.tm.szb.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tm.szb.commons.BizException;
import com.tm.szb.commons.ResultEnums;
import com.tm.szb.dto.SetmealDTO;
import com.tm.szb.dto.SetmealDishDTO;
import com.tm.szb.entity.Category;
import com.tm.szb.entity.Setmeal;
import com.tm.szb.entity.SetmealDish;
import com.tm.szb.enums.StatusEnums;
import com.tm.szb.mapper.SetmealMapper;
import com.tm.szb.service.CategoryService;
import com.tm.szb.service.SetmealDishService;
import com.tm.szb.service.SetmealService;
import com.tm.szb.vo.SetmealDishVO;
import com.tm.szb.vo.SetmealVO;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.builder.BuilderException;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {

    private final SetmealDishService setmealDishService;

    private final CategoryService categoryService;

    public SetmealServiceImpl(SetmealDishService setmealDishService, CategoryService categoryService) {
        this.setmealDishService = setmealDishService;
        this.categoryService = categoryService;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveSetmeal(SetmealDTO setmealDTO) {
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO,setmeal);
        setmeal.setStatus(StatusEnums.ENABLE.getCode());
        baseMapper.insert(setmeal);
        Long setmealId = setmeal.getId();
        List<SetmealDishDTO> setmealDishDTOS = setmealDTO.getSetmealDishes();
        List<SetmealDish> setmealDishList = setmealDishDTOS.stream().map(setmealDishDTO -> {
            SetmealDish setmealDish = new SetmealDish();
            BeanUtils.copyProperties(setmealDishDTO, setmealDish);
            setmealDish.setSetmealId(setmealId);
            return setmealDish;
        }).collect(Collectors.toList());
        setmealDishService.saveBatch(setmealDishList);
    }

    @Override
    public Page<SetmealVO> pageList(Integer page, Integer pageSize, String name) {
        Page<Setmeal> page1 = new Page<>(page,page);
        //查询套餐列表
        baseMapper.selectPage(page1,new LambdaQueryWrapper<Setmeal>()
                .like(StringUtils.isNotBlank(name),Setmeal::getName,name)
                .eq(Setmeal::getIsDeleted,0)
                .orderByDesc(Setmeal::getUpdateTime));
        List<Setmeal> records = page1.getRecords();
        //批量查询套餐分类信息
        Set<Long> categoryIds = records.stream().map(Setmeal::getCategoryId).collect(Collectors.toSet());
        List<Category> categoryList = categoryService.listByIds(categoryIds);
        //将查询出来的分类信息转换成map
        Map<Long, String> categoryMap = categoryList.stream().collect(Collectors.toMap(Category::getId, e -> e.getName()));


        Page<SetmealVO> page2 = new Page<>(page1.getCurrent(),page1.getSize(),page1.getTotal());
        List<SetmealVO> setmealVOList = records.stream().map(setmeal -> {
            SetmealVO setmealVO = new SetmealVO();
            BeanUtils.copyProperties(setmeal, setmealVO);
            setmealVO.setCategoryName(categoryMap.get(setmeal.getCategoryId()));
            return setmealVO;
        }).collect(Collectors.toList());
        page2.setRecords(setmealVOList);
        return page2;
    }

    @Override
    public SetmealVO getSetMeal(Long id) {
        //查询套餐表
        Setmeal setmeal = baseMapper.selectById(id);
        //查询套餐菜品表
        List<SetmealDish> setmealDishes = setmealDishService.list(new LambdaQueryWrapper<SetmealDish>()
                .eq(SetmealDish::getSetmealId, id)
                .eq(SetmealDish::getIsDeleted,0));
        SetmealVO setmealVO = new SetmealVO();
        BeanUtils.copyProperties(setmeal,setmealVO);
        List<SetmealDishVO> collect = setmealDishes.stream().map(setmealDish -> {
            SetmealDishVO setmealDishVO = new SetmealDishVO();
            BeanUtils.copyProperties(setmealDish, setmealDishVO);
            return setmealDishVO;
        }).collect(Collectors.toList());
        setmealVO.setSetmealDishes(collect);
        return setmealVO;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSetmeal(SetmealDTO setmealDTO) {
        Long setmealId = setmealDTO.getId();
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO,setmeal);
        baseMapper.updateById(setmeal);
        setmealDishService.remove(new LambdaQueryWrapper<SetmealDish>().eq(SetmealDish::getSetmealId,setmealId));
        List<SetmealDishDTO> setmealDishes = setmealDTO.getSetmealDishes();
        List<SetmealDish> setmealDishList = setmealDishes.stream().map(setmealDishDTO -> {
            SetmealDish setmealDish = new SetmealDish();
            BeanUtils.copyProperties(setmealDishDTO, setmealDish);
            setmealDish.setSetmealId(setmealId);
            return setmealDish;
        }).collect(Collectors.toList());
        setmealDishService.saveBatch(setmealDishList);
    }



    @Override
    public void updateStatus(Integer status, List<Long> idList) {
        List<Setmeal> setmealList = idList.stream().map(id -> {
            Setmeal setmeal = new Setmeal();
            setmeal.setId(id);
            setmeal.setStatus(status);
            return setmeal;
        }).collect(Collectors.toList());

        super.updateBatchById(setmealList);
    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteSetmeal(List<Long> longList) {
        //判断是否在启售状态
        int count = super.count(new LambdaQueryWrapper<Setmeal>().in(Setmeal::getId, longList)
                    .eq(Setmeal::getIsDeleted,0));
        if (count > 0){
            throw new BizException(ResultEnums.NOT_DEL);
        }
        List<Setmeal> setmealList = longList.stream().map(id -> {
            Setmeal setmeal = new Setmeal();
            setmeal.setId(id);
            setmeal.setIsDeleted(1);
            return setmeal;
        }).collect(Collectors.toList());
        super.updateBatchById(setmealList);

        SetmealDish setmealDish = new SetmealDish();

        LambdaQueryWrapper<SetmealDish> wrapper = new LambdaQueryWrapper();
        setmealDish.setIsDeleted(1);
        wrapper.in(SetmealDish::getSetmealId,longList);
        setmealDishService.update(setmealDish,wrapper);

    }
}

